# -*- coding:utf-8 -*-
# created on 2016/5/5


from mathsolver.functions.base import *
from sympy import Abs, simplify, solveset
from mathsolver.functions.yuan.base import default_symbols
from mathsolver.functions.zhixian.lineOthers import GraphFixedPoint
from mathsolver.functions.zhixian.property import GetLiangDianJuLi
from mathsolver.functions.zhixian.length import DianToXianJuLi
from mathsolver.functions.zhixian.base import point_to_line_dis2
from mathsolver.functions.root.jiefangchen import JieFangChen
from mathsolver.functions.yuan.property import GetYuanRadius, GetYuanCenterPoint


# 判断点与圆的位置关系
class PointPosYuan(BaseFunction):
    """
    点P(2,5)与圆x^{2}+y^{2}=24的位置关系是()
    """
    def solver(self, *args):
        liangdianju = args[0].sympify()
        banjing = args[1].sympify()
        juli_symbols = liangdianju.free_symbols
        banjing_symbols = banjing.free_symbols
        if not juli_symbols and not banjing_symbols:
            if liangdianju > banjing:
                self.steps.append(["", "∵ %s > %s" % (new_latex(liangdianju), new_latex(banjing))])
                self.steps.append(["", "∴ 点在圆外"])
                self.output.append(BaseNumber(1))  # 1代表点在圆外
            elif liangdianju == banjing:
                self.steps.append(["", "∵ %s = %s" % (new_latex(liangdianju), new_latex(banjing))])
                self.steps.append(["", "∴ 点在圆上"])
                self.output.append(BaseNumber(2))  # 2代表点在圆上
            elif liangdianju < banjing:
                self.steps.append(["", "∵ %s < %s" % (new_latex(liangdianju), new_latex(banjing))])
                self.steps.append(["", "∴ 点在圆内"])
                self.output.append(BaseNumber(3))  # 3代表点在圆内
            self.label.add("判断点与圆的位置关系-不含参")
        else:
            symbols = juli_symbols | banjing_symbols
            if len(symbols) == 1:
                target_symbol = list(symbols)[0]
                juli2 = liangdianju ** 2
                banjing2 = banjing ** 2
                expr = juli2 - banjing2
                answer1 = solveset(expr > S.Zero, target_symbol, S.Reals)
                answer2 = solveset(expr < S.Zero, target_symbol, S.Reals)
                if answer1.is_EmptySet:
                    self.steps.append(["", "∵ %s < %s" % (new_latex(liangdianju), new_latex(banjing))])
                    self.steps.append(["", "∴ 点在圆内"])
                    self.output.append(BaseNumber(3))
                elif answer2.is_EmptySet:
                    self.steps.append(["", "∵ %s > %s" % (new_latex(liangdianju), new_latex(banjing))])
                    self.steps.append(["", "∴ 点在圆外"])
                    self.output.append(BaseNumber(1))
            self.label.add("判断点与圆的位置关系-含参")
        return self


# 判断点与圆的位置关系
class PointPosYuanParams(BaseFunction):
    def solver(self, *args):
        liangdianju = args[0].sympify()
        banjing = args[1].sympify()
        juli_symbols = liangdianju.free_symbols
        banjing_symbols = banjing.free_symbols
        if not juli_symbols and not banjing_symbols:
            if liangdianju > banjing:
                self.steps.append(["", "∵ %s > %s" % (new_latex(liangdianju), new_latex(banjing))])
                self.steps.append(["", "∴ 点在圆外"])
                self.output.append(BaseNumber(1))  # 1代表点在圆外
            elif liangdianju == banjing:
                self.steps.append(["", "∵ %s = %s" % (new_latex(liangdianju), new_latex(banjing))])
                self.steps.append(["", "∴ 点在圆上"])
                self.output.append(BaseNumber(2))  # 2代表点在圆上
            elif liangdianju < banjing:
                self.steps.append(["", "∵ %s < %s" % (new_latex(liangdianju), new_latex(banjing))])
                self.steps.append(["", "∴ 点在圆内"])
                self.output.append(BaseNumber(3))  # 3代表点在圆内
            self.label.add("判断点与圆的位置关系-不含参")
        else:
            symbols = juli_symbols | banjing_symbols
            if len(symbols) == 1:
                target_symbol = list(symbols)[0]
                juli2 = liangdianju ** 2
                banjing2 = banjing ** 2
                expr = juli2 - banjing2
                answer1 = solveset(expr > S.Zero, target_symbol, S.Reals)
                answer2 = solveset(expr < S.Zero, target_symbol, S.Reals)
                if answer1.is_EmptySet:
                    self.steps.append(["", "∵ %s < %s" % (new_latex(liangdianju), new_latex(banjing))])
                    self.steps.append(["", "∴ 点在圆内"])
                    self.output.append(BaseNumber(3))
                elif answer2.is_EmptySet:
                    self.steps.append(["", "∵ %s > %s" % (new_latex(liangdianju), new_latex(banjing))])
                    self.steps.append(["", "∴ 点在圆外"])
                    self.output.append(BaseNumber(1))
            self.label.add("判断点与圆的位置关系-含参")
        return self


# 判断直线与圆的位置关系
class LinePosYuan(BaseFunction):
    """
    圆x^{2}+y^{2}=1与直线2x+3y-2=0的位置关系是()
    """
    def solver(self, *args):
        juli = args[0].sympify()
        banjing = args[1].sympify()
        banjing = simplify(banjing ** 2)
        if juli - banjing > 0:
            self.steps.append(["", "∵ %s > %s" % (new_latex(juli), new_latex(banjing))])
            self.output.append(BaseNumber(3))
            self.steps.append(["", "∴ 圆与直线相离"])
        elif juli - banjing == 0:
            self.steps.append(["", "∵ %s = %s" % (new_latex(juli), new_latex(banjing))])
            self.output.append(BaseNumber(2))
            self.steps.append(["", "∴ 圆与直线相切"])
        elif juli - banjing < 0:
            self.steps.append(["", "∵ %s < %s" % (new_latex(juli), new_latex(banjing))])
            self.output.append(BaseNumber(1))
            self.steps.append(["", "∴ 圆与直线相交"])
        self.label.add("判断直线与圆的位置关系")
        return self


# 判断含参直线与圆的位置关系
class LinePosYuan002(BaseFunction):
    """
    对任意的实数k,直线y=kx+1与圆x^{2}+y^{2}=2的位置关系是()
    """
    def solver(self, *args):
        zhixian = args[0].sympify()
        yuan = args[1].sympify()
        zhixian_expr = (zhixian[0] - zhixian[1]).expand().simplify()
        symx, symy = default_symbols(zhixian_expr)
        zhixian_symbols = zhixian_expr.free_symbols.difference([symx, symy])
        assert zhixian_symbols
        step1 = GraphFixedPoint().solver(args[0])
        self.steps += step1.steps
        self.label.update(step1.label)
        step2 = GetYuanCenterPoint().solver(args[1])
        self.label.update(step2.label)
        self.steps += step2.steps
        step3 = GetYuanRadius().solver(args[1])
        self.label.update(step3.label)
        banjing = step3.output[0].value
        self.steps += step3.steps
        step4 = GetLiangDianJuLi().solver(step1.output[0], step2.output[0])
        self.label.update(step4.label)
        self.steps += step4.steps
        juli = step4.output[0].value
        if juli - banjing < 0:
            self.steps.append(["", "∵%s < %s" % (new_latex(juli), new_latex(banjing))])
            self.output.append(BaseNumber(1))
            self.steps.append(["", "∴直线与圆相交"])
        elif juli - banjing == 0:
            step5 = DianToXianJuLi().solver(step2.output[0], args[0])
            self.steps.append(["当%s与%s相切时," % (
                BaseZhiXian({"name": "", "value": [zhixian[0], zhixian[1]]}).printing(),
                BaseYuan({"name": "", "value": [yuan[0], yuan[1]]}).printing()),
                               BaseEq([step5.output[0].value, banjing]).printing()])
            eq_left = point_to_line_dis2(step2.output[0], args[0])
            eq_right = banjing ** 2
            step6 = JieFangChen().solver(BaseEq([eq_left, eq_right])).output[0].value
            jie = step6[list(step6.keys())[0]]
            if not jie:
                self.steps.append(["", "方程无解，所以直线与圆不可能相切"])
                self.steps.append(["", "∴直线与圆相交"])
                self.output.append(BaseNumber(1))
            else:
                self.steps.append(["", "∴直线与圆相交或相切"])
        elif juli - banjing > 0:
            self.steps.append(["", "无法确定"])
        self.label.add("判断恒过定点的直线系与圆的位置关系")
        return self


# 根据直线与圆的位置关系求参
class LinePosYuanParams(BaseFunction):
    """
    若直线x+y-a=0与圆x^{2}+y^{2}-2x=0相切,则a的值为().
    """
    def solver(self, *args):
        juli = args[0].sympify()
        banjing = args[1].sympify()
        text = args[2]
        flag = [0, 0, 0, 0]  # 相离/没有公共点;相切/只有一个公共点;相交/有两个公共点;相切&相交/有公共点
        if "相离" in text:
            flag[0] = 1
        if "相切" in text:
            flag[1] = 1
        if "相交" in text:
            flag[2] = 1
        if "公共点" in text or "交点" in text:
            flag[3] = 1

        if flag[0] == 1:
            self.steps.append(["", "∵圆与直线相离"])
            self.steps.append(["", "∴ %s > %s" % (new_latex(juli), new_latex(banjing))])
            self.output.append(BaseIneq([juli, ">", banjing]))
            self.label.add("直线与圆相离，求参")
        elif flag[1] == 1:
            self.steps.append(["", "∵圆与直线相切"])
            self.steps.append(["", "∴ %s = %s" % (new_latex(juli), new_latex(banjing))])
            self.output.append(BaseEq([juli, banjing]))
            self.label.add("直线与圆相切，求参")
        elif flag[2] == 1:
            self.steps.append(["", "∵圆与直线相交"])
            self.steps.append(["", "∴ %s < %s" % (new_latex(juli), new_latex(banjing))])
            self.output.append(BaseIneq([juli, "<", banjing]))
            self.label.add("直线与圆相交，求参")
        elif flag[3] == 1:
            self.steps.append(["", "∵圆与直线有公共点"])
            self.steps.append(["", "∴ %s <= %s" % (new_latex(juli), new_latex(banjing))])
            self.output.append(BaseIneq([juli, "<=", banjing]))
            self.label.add("圆与直线有公共点，求参")
        return self


# 判断圆与圆的位置关系
class YuanPosYuan(BaseFunction):
    """
    两圆x^{2}+y^{2}=4和(x-3)^{2}+(y-4)^{2}=9的位置关系是()
    """
    def solver(self, *args):
        banjing1 = args[0].sympify()
        banjing2 = args[1].sympify()
        yuanxinjuli = args[2].sympify()
        if yuanxinjuli > banjing1 + banjing2:
            self.steps.append(["", "∵%s > %s + %s" % (new_latex(yuanxinjuli), new_latex(banjing1),
                                                      new_latex(banjing2))])
            self.steps.append(["", "∴ 两圆的位置关系为相离"])
            self.output.append(BaseNumber(1))
        elif yuanxinjuli == banjing1 + banjing2:
            self.steps.append(["", "∵%s = %s + %s" % (new_latex(yuanxinjuli), new_latex(banjing1),
                                                      new_latex(banjing2))])
            self.steps.append(["", "∴ 两圆的位置关系为外切"])
            self.output.append(BaseNumber(2))
        elif banjing1 + banjing2 > yuanxinjuli > Abs(banjing1 - banjing2):
            self.steps.append(["", "∵%s > %s + %s 且 %s < %s - %s" % (
                new_latex(yuanxinjuli), new_latex(banjing1), new_latex(banjing2), new_latex(yuanxinjuli),
                new_latex(max(banjing1, banjing2)), new_latex(min(banjing1, banjing2)))])
            self.steps.append(["", "∴ 两圆的位置关系为相交"])
            self.output.append(BaseNumber(3))
        elif yuanxinjuli == Abs(banjing1 - banjing2):
            self.steps.append(["", "∵%s = %s - %s" % (new_latex(yuanxinjuli), new_latex(max(banjing1, banjing2)),
                                                      new_latex(min(banjing1, banjing2)))])
            self.steps.append(["", "∴ 两圆的位置关系为内切"])
            self.output.append(BaseNumber(4))
        elif yuanxinjuli < Abs(banjing1 - banjing2):
            self.steps.append(["", "∵%s < %s - %s" % (new_latex(yuanxinjuli), new_latex(max(banjing1, banjing2)),
                                                      new_latex(min(banjing1, banjing2)))])
            self.steps.append(["", "∴ 两圆的位置关系为内含"])
            self.output.append(BaseNumber(5))
        self.label.add("判断两圆的位置关系")
        return self


# 根据圆与圆的位置关系，求参
class YuanPosYuanParams(BaseFunction):
    """
    圆C_{1}:(x-m)^{2}+(y+2)^{2}=9与圆C_{2}:(x+1)^{2}+(y-m)^{2}=4外切,则m的值为()
    """
    def solver(self, *args):
        juli = args[0].sympify()
        banjing1 = args[1].sympify()
        banjing2 = args[2].sympify()
        text = args[3]
        flag = [0, 0, 0, 0, 0]  # 相离;外切;相交;内切;内含
        if "相离" in text:
            flag[0] = 1
        if "外切" in text:
            flag[1] = 1
        if "相交" in text:
            flag[2] = 1
        if "内切" in text:
            flag[3] = 1
        if "内含" in text:
            flag[4] = 1

        if flag[0] == 1:
            self.steps.append(["", "∵圆与圆相离"])
            self.steps.append(["", "∴ %s > %s + %s" % (new_latex(juli), new_latex(banjing1), new_latex(banjing2))])
            self.output.append(BaseIneq([juli, ">", banjing1 + banjing2]))
            self.label.add("直线与圆相离，求参")
        elif flag[1] == 1:
            self.steps.append(["", "∵圆与圆外切"])
            self.steps.append(["", "∴ %s = %s + %s" % (new_latex(juli), new_latex(banjing1), new_latex(banjing2))])
            self.output.append(BaseEq([juli, banjing1 + banjing2]))
            self.label.add("圆与圆外切，求参")
        elif flag[2] == 1:
            self.steps.append(["", "∵圆与圆相交"])
            self.steps.append(["", "∴ %s - %s < %s < %s + %s" % (new_latex(max(banjing1, banjing2)),
                                                                 new_latex(min(banjing1, banjing2)),
                                                                 new_latex(juli), new_latex(max(banjing1, banjing2)),
                                                                 new_latex(min(banjing1, banjing2)))])
            self.output.append(BaseIneqs([max(banjing1, banjing2) - min(banjing1, banjing2), "<",
                                          juli, "<", max(banjing1, banjing2) + min(banjing1, banjing2)]))
            self.label.add("圆与圆相交，求参")
        elif flag[3] == 1:
            self.steps.append(["", "∵圆与圆内切"])
            v = Abs(banjing1 - banjing2)
            self.steps.append(["", "∴ %s = %s" % (new_latex(juli), new_latex(v))])
            self.output.append(BaseEq([juli, v]))
            self.label.add("圆与圆内切，求参")
        elif flag[4] == 1:
            self.steps.append(["", "∵圆与圆内含"])
            self.steps.append(["", "∴ %s < %s - %s" % (new_latex(juli), new_latex(max(banjing1, banjing2)),
                                                       new_latex(min(banjing1, banjing2)))])
            self.output.append(BaseIneq([juli, "<", max(banjing1, banjing2) - min(banjing1, banjing2)]))
            self.label.add("圆与圆内切，求参")
        return self


# 求两圆的公切线的条数
class TwoYuanCommQieLen(BaseFunction):
    def solver(self, *args):
        guanxi = args[0].sympify()
        if guanxi == 1:
            self.steps.append(["", "∵圆与圆相离"])
            self.steps.append(["", "∴存在4条公切线"])
            self.output.append(BaseNumber(1))
        elif guanxi == 2:
            self.steps.append(["", "∵圆与圆外切"])
            self.steps.append(["", "∴存在3条公切线"])
            self.output.append(BaseNumber(2))
        elif guanxi == 3:
            self.steps.append(["", "∵圆与圆相交"])
            self.steps.append(["", "∴存在2条公切线"])
            self.output.append(BaseNumber(3))
        elif guanxi == 4:
            self.steps.append(["", "∵圆与圆内切"])
            self.steps.append(["", "∴存在1条公切线"])
            self.output.append(BaseNumber(4))
        elif guanxi == 5:
            self.steps.append(["", "∵圆与圆内含"])
            self.steps.append(["", "∴不存在公切线"])
            self.output.append(BaseNumber(5))
        self.label.add("求两圆的公切线的条数")
        return self


if __name__ == '__main__':
    pass
